package com.baidu.encrypt.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baidu.encrypt.common.utils.SM3Util;
import com.baidu.encrypt.common.utils.SM4Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.StringJoiner;

@Slf4j
@Component
public class EncryptMetaObjectHandler implements MetaObjectHandler {

    @Autowired
    private SM4Util sm4Util;

    @Override
    public void insertFill(MetaObject metaObject) {
        encryptFieldsAndGenerateSm3(metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        encryptFieldsAndGenerateSm3(metaObject);
    }

    private void encryptFieldsAndGenerateSm3(MetaObject metaObject) {
        Object obj = metaObject.getOriginalObject();
        StringJoiner plainConcat = new StringJoiner("");

        try {
            for (Field field : obj.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                String fieldName = field.getName();

                if ("id".equalsIgnoreCase(fieldName) || "sm3".equalsIgnoreCase(fieldName)) {
                    continue;
                }

                Object value = field.get(obj);
                String strValue = value == null ? "" : value.toString();

                // 明文拼接用于 SM3
                plainConcat.add(strValue);

                // SM4 加密
                String encrypted = sm4Util.encrypt(strValue);
                field.set(obj, encrypted);
            }

            // 生成 SM3 摘要
            Field sm3Field = obj.getClass().getDeclaredField("sm3");
            sm3Field.setAccessible(true);
            sm3Field.set(obj, SM3Util.encrypt(plainConcat.toString()));

        } catch (Exception e) {
            log.error("加密处理失败", e);
        }
    }
}
